
#define R_EAX 0
#define R_ECX 1
#define R_EDX 2
#define R_EBX 3
#define R_ESP 4
#define R_EBP 5
#define R_ESI 6
#define R_EDI 7

#define R_AL 0
#define R_CL 1
#define R_DL 2
#define R_BL 3
#define R_AH 4
#define R_CH 5
#define R_DH 6
#define R_BH 7

#define R_ES 0
#define R_CS 1
#define R_SS 2
#define R_DS 3
#define R_FS 4
#define R_GS 5

/* segment descriptor fields */
#define DESC_G_MASK     (1 << 23)
#define DESC_B_SHIFT    22
#define DESC_B_MASK     (1 << DESC_B_SHIFT)
#define DESC_L_SHIFT    21 /* x86_64 only : 64 bit code segment */
#define DESC_L_MASK     (1 << DESC_L_SHIFT)
#define DESC_AVL_MASK   (1 << 20)
#define DESC_P_MASK     (1 << 15)
#define DESC_DPL_SHIFT  13
#define DESC_DPL_MASK   (3 << DESC_DPL_SHIFT)
#define DESC_S_MASK     (1 << 12)
#define DESC_TYPE_SHIFT 8
#define DESC_TYPE_MASK  (15 << DESC_TYPE_SHIFT)
#define DESC_A_MASK     (1 << 8)

#define DESC_CS_MASK    (1 << 11) /* 1=code segment 0=data segment */
#define DESC_C_MASK     (1 << 10) /* code: conforming */
#define DESC_R_MASK     (1 << 9)  /* code: readable */

#define DESC_E_MASK     (1 << 10) /* data: expansion direction */
#define DESC_W_MASK     (1 << 9)  /* data: writable */

#define DESC_TSS_BUSY_MASK (1 << 9)

#define CR0_PE_SHIFT 0
#define CR0_MP_SHIFT 1

#define CR0_PE_MASK  (1 << 0)
#define CR0_MP_MASK  (1 << 1)
#define CR0_EM_MASK  (1 << 2)
#define CR0_TS_MASK  (1 << 3)
#define CR0_ET_MASK  (1 << 4)
#define CR0_NE_MASK  (1 << 5)
#define CR0_WP_MASK  (1 << 16)
#define CR0_AM_MASK  (1 << 18)
#define CR0_PG_MASK  (1 << 31)

/* eflags masks */
#define CC_C	0x0001
#define CC_P	0x0004
#define CC_A	0x0010
#define CC_Z	0x0040
#define CC_S	0x0080
#define CC_O	0x0800

#define TMP_C	0
#define TMP_P	1
#define TMP_A	2
#define TMP_Z	3
#define TMP_S	4
#define TMP_O	5


#define TF_SHIFT   8
#define IOPL_SHIFT 12
#define VM_SHIFT   17

#define TF_MASK 		0x00000100
#define IF_MASK 		0x00000200
#define DF_MASK 		0x00000400
#define IOPL_MASK		0x00003000
#define NT_MASK	         	0x00004000
#define RF_MASK			0x00010000
#define VM_MASK			0x00020000
#define AC_MASK			0x00040000
#define VIF_MASK                0x00080000
#define VIP_MASK                0x00100000
#define ID_MASK                 0x00200000

/* hidden flags. */
#define HF_CPL_SHIFT         0
#define HF_CPL_MASK          (3 << HF_CPL_SHIFT)

#define EXCP00_DIVZ	0
#define EXCP01_DB	1
#define EXCP02_NMI	2
#define EXCP03_INT3	3
#define EXCP04_INTO	4
#define EXCP05_BOUND	5
#define EXCP06_ILLOP	6
#define EXCP07_PREX	7
#define EXCP08_DBLE	8
#define EXCP09_XERR	9
#define EXCP0A_TSS	10
#define EXCP0B_NOSEG	11
#define EXCP0C_STACK	12
#define EXCP0D_GPF	13
#define EXCP0E_PAGE	14
#define EXCP10_COPR	16
#define EXCP11_ALGN	17
#define EXCP12_MCHK	18

#ifndef __ASSEMBLY__

typedef struct SegmentCache {
	uint32_t selector;
	uint32_t base;
	uint32_t limit;
	uint32_t flags;
} SegmentCache;

#define CPU_NB_REGS32 8

typedef struct CPUX86State {
	/* standard registers */
	uint32_t regs[CPU_NB_REGS32];
	uint32_t eip;
	uint32_t eflags;
	int32_t df; /* D flag : 1 if D = 0, -1 if D = 1 */
	/* segments */
	SegmentCache segs[6]; /* selector values */
	SegmentCache ldt;
	SegmentCache gdt; /* only base and limit are used */
	SegmentCache idt; /* only base and limit are used */

	uint32_t cr[5]; /* NOTE: cr1 is unused */

	uint32_t hflags; /* TB flags, see HF_xxx constants. These flags
				are known at translation time. */
} CPUX86State;

static inline void cpu_load_seg_cache(CPUX86State *env,
	int seg_reg, uint32_t selector,
	uint32_t base,
	uint32_t limit,
	uint32_t flags)
{
	SegmentCache *sc;

	sc = &env->segs[seg_reg];
	sc->selector = selector;
	sc->base = base;
	sc->limit = limit;
	sc->flags = flags;
}

void cpu_dump_state(CPUX86State *env, FILE *f,
                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...));
void cpu_reset(CPUX86State *env);
CPUX86State *cpu_init(void);
void cpu_exit(CPUX86State *env);

#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

#define offset(x)	(offsetof(CPUX86State, x))
#define offset_reg(ot, x)	(((ot == OT_BYTE) && ((x) > 3)) ?	\
	offsetof(CPUX86State, regs[(x) & 3] + 1) :	\
	offsetof(CPUX86State, regs[x]))
#define offset_sreg(x)	(offsetof(CPUX86State, segs[x]))
#define offset_cr(x)	(offsetof(CPUX86State, cr[x]))
#endif
